/*
 * Project Name: jmax
 * File Name: DeviceMonitor.java
 * Copyright: Copyright(C) 1985-2015 ZKTeco Inc. All rights reserved.
 */
package com.xdtech.hotel.protocol.manager;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.xdtech.common.service.impl.BaseService;
import com.xdtech.core.model.BaseModel;
import com.xdtech.hotel.model.Device;
import com.xdtech.hotel.monitor.ClientMonitor;
import com.xdtech.hotel.protocol.vo.RCUDevice;
import com.xdtech.hotel.util.HotelConstants;
import com.xdtech.hotel.util.RedisUtils;

/**
 * 
 * @version TODO 添加版本
 * @see 相关类或方法，不需要请删除此行
 * @since 2015-4-24 下午1:53:28
 */
public class DeviceMonitor
{
	private static Log log = LogFactory.getLog(DeviceMonitor.class);
	//监控的设备map集合
	public static Map<String, RCUDevice> monitorDevices = new ConcurrentHashMap();
	/**
	 * 初始化房间监控数据
	 * 
	 * @author max.zheng
	 * @since 2015-4-8 下午5:32:18
	 * @param baseService
	 */
	public static void initMonitorDatas(BaseService<BaseModel> baseService) {
		log.info("初始化设备监控数据......");
		Object obj = baseService.findByHql("from Device");
		List<Device> devices = (List<Device>) obj;
		RCUDevice tempDevice = null;
		for (Device device : devices)
		{
			initRcuDevice(device);
		}
		//启动设备状态检测线程
		startDeviceStatusCheckThread();
		log.info("初始化设备监控数据......结束");
	}



	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-3下午3:52:53
	 * @modified by
	 * @param device
	 */
	public static void initRcuDevice(Device device) {
		RCUDevice tempDevice;
		tempDevice =  new RCUDevice(device.getId().toString(),device.getSn(), device.getIp(), device.getPort(), HotelConstants.DEV_STATUS_LINKING,device.getName(),System.currentTimeMillis());
		//设置初始状态
//			RedisUtils.setDevStatusInfo(tempDevice);
		//设置初始虚拟访问时间
//			RedisUtils.setDevRequestTime(device.getSn(), System.currentTimeMillis());
		
		monitorDevices.put(tempDevice.getSn(), tempDevice);
	}
	
	
	
	public static void updateRcuDevice(String sn,String status) {
//		RCUDevice rcuDevice = RedisUtils.getDevStatusInfo(sn);
		RCUDevice rcuDevice = monitorDevices.get(sn);
		if (null != rcuDevice)
		{
			rcuDevice.setStatus(status);
//			RedisUtils.setDevStatusInfo(rcuDevice);
			monitorDevices.put(sn, rcuDevice);
			//如果有客户端链接，同时更新推送给客户端
			ClientMonitor.addDeviceMonitorData(rcuDevice);
		}
	}
	/**
	 * 判断设备是否在线
	 * 
	 * @author max.zheng
	 * @create 2015-5-3下午2:58:07
	 * @modified by
	 * @param sn
	 * @return
	 */
	public static boolean deviceIsOnline(String sn) {
//		RCUDevice rcuDevice = monitorDevices.get(sn);
//		return HotelConstants.DEV_STATUS_ONLINE.equals(rcuDevice.getStatus());
		return true;
	}
	/**
	 * 设置设备最近访问时间
	 * 
	 * @author <a href="max.zheng@zkteco.com">郑志雄</>
	 * @since 2015-4-24 下午5:00:04
	 * @param sn
	 * @param time
	 */
	public static void updateDeviceLastestRequestTime(String sn,long time) {
//		RedisUtils.setDevRequestTime(sn, time);
		RCUDevice rcuDevice = monitorDevices.get(sn);
		rcuDevice.setLastRequestTime(time);
	}
	
	/**
	 * 开启设备状态监控线程
	 * @author max
	 * @since 2015-4-24 下午2:25:20
	 */
	private static void startDeviceStatusCheckThread()
	{
		new Thread(new Runnable()
		{
			@Override
			public void run()
			{
				while (true)
				{
					try
					{
//						Map<String, Long> requestMap = RedisUtils.getAllDeviceRequests();
//						for (String key : requestMap.keySet())
//						{
//							long lastRequestTime = requestMap.get(key);
//							if (System.currentTimeMillis()-lastRequestTime>30000)
//							{
//								//超过30秒，自动状态更改离线
//								updateRcuDevice(key, HotelConstants.DEV_STATUS_OFFLINE);
//							}
//						}
						for (String sn : monitorDevices.keySet()) {
							RCUDevice device = monitorDevices.get(sn);
							if (System.currentTimeMillis()-device.getLastRequestTime()>30000) {
								updateRcuDevice(sn, HotelConstants.DEV_STATUS_OFFLINE);
							}
						}
						//30秒检测一次
						Thread.sleep(30000);
					}
					catch (Exception e)
					{
						log.error("设备状态检测线程异常",e);
					}
				}
			}
		}, "DeviceStatusCheckThread").start();
	}
}
